﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Diagnostics;
using System.Net;
using XUCore.NetCore.DynamicWebApi.Helper;

namespace XUCore.NetCore.RestFul
{
    /// <summary>
    /// Api返回过滤器
    /// </summary>
    public class RestFulFormatterFilter : ActionFilterAttribute, IActionFilter
    {
        private string ElapsedField = "ElapsedTime";
        private bool Open = true;

        public RestFulFormatterFilter(bool Open = true, string ElapsedField = "ElapsedTime")
        {
            this.Open = Open;
            this.ElapsedField = ElapsedField;
        }

        private Stopwatch stopwatch = new Stopwatch();

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (Open)
            {
                if (stopwatch == null)
                    stopwatch = new Stopwatch();
                stopwatch.Reset();
                stopwatch.Restart();
            }
        }

        public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
        {
            if (Open)
            {
                if (stopwatch == null)
                    stopwatch = new Stopwatch();
                stopwatch.Stop();


                var descriptor = (ControllerActionDescriptor)actionExecutedContext.ActionDescriptor;

                var controllerAttr = descriptor.ControllerTypeInfo.GetSingleAttributeOrNull<NoRestFulFormatterAttribute>();

                if (controllerAttr != null) return;

                var reType = actionExecutedContext.Result?.GetType();

                if (reType == typeof(Result))
                {
                    var res = (Result)actionExecutedContext.Result;
                    var obj = new ObjectResult(new Result<object>(res.Code, res.SubCode, res.Message, res?.Data)
                    {
                        ElapsedTime = stopwatch.ElapsedMilliseconds,
                        OperationTime = res.OperationTime
                    });
                    obj.StatusCode = (int)HttpStatusCode.OK;
                    actionExecutedContext.Result = obj;
                }
                else if (reType == typeof(ObjectResult))
                {
                    var res = (ObjectResult)actionExecutedContext.Result;
                    if (res != null && res.Value != null && res.Value.GetType().Name == typeof(Result<>).Name)
                    {
                        res.Value?.GetType().GetProperty(ElapsedField).SetValue(res.Value, stopwatch.ElapsedMilliseconds);
                        res.StatusCode = (int)HttpStatusCode.OK;
                        actionExecutedContext.Result = res;
                    }
                    else
                    {
                        var actionAttr = descriptor.MethodInfo.GetSingleAttributeOrNull<NoRestFulFormatterAttribute>();

                        if (actionAttr != null) return;

                        var obj = new ObjectResult(new Result<object>(StateCode.Success, "SUCCESS", "操作成功", res?.Value)
                        {
                            ElapsedTime = stopwatch.ElapsedMilliseconds
                        });
                        obj.StatusCode = (int)HttpStatusCode.OK;
                        actionExecutedContext.Result = obj;
                    }
                }
            }
        }
    }
}